package project.layer.ant;

import framework.events.EventBroker;
import project.data.FeasibilityData;
import project.events.antEvents.FeasibilityAntCreatedEvent;
import project.events.antEvents.FeasibilityAntDiedEvent;
import project.layer.agents.PackagePointAgent;
import project.layer.physical.Crossroad;
import project.layer.physical.Road;

public class FeasibilityAnt extends HoppingAnt{
	

	private final long initialPheromoneCount;

	
	public boolean isFromPickUpPoint() {
		return getSendingAgent().isPickUpPointAgent();
	}

	public FeasibilityAnt(int maxHops, PackagePointAgent sendingAgent, Crossroad location, int initialPheromones){
		super(sendingAgent, location, maxHops);
		this.initialPheromoneCount = initialPheromones;
		EventBroker.getEventBroker().notifyAll(new FeasibilityAntCreatedEvent(this));
	}
	
	FeasibilityAnt(int maxHops, int currentHopCount, PackagePointAgent sendingAgent, Crossroad location, Road lastRoad, long travelledDistance, long initialPheromones){
		super(sendingAgent, location, maxHops, currentHopCount , lastRoad, travelledDistance);
		this.initialPheromoneCount = initialPheromones;
		EventBroker.getEventBroker().notifyAll(new FeasibilityAntCreatedEvent(this));
	}

	@Override
	public void cloneAndSpread() {
		for(Road road : getLocation().getIncomingConnections()){
			if(shouldDropPheromones(road) &&  !equalsRoadLastTraveled(road)){
				
				Crossroad nextCrossroad = road.getOtherConnector(getLocation());

				FeasibilityAnt feasibilityAnt = new FeasibilityAnt(getMaxHops(), getCurrentHopCount(), getSendingAgent(), nextCrossroad, road, getTravelledDistance(), getInitialPheromoneCount());
				feasibilityAnt.increaseTravelledDistance(road.getLength());
				
			}
		}
	}

	@Override
	public PackagePointAgent getSendingAgent() {
		return (PackagePointAgent)sendingAgent;
	}

	@Override
	public void processAntTick() {
//		if(!this.getCrossroad().hasMoreOrEqualAmountOfPheromonesThen(this.getPheromoneCount())){
		if(getPheromoneSmell() > 50){
			this.dropPheromones();
			cloneAndSpread();
		}
		this.die();
		
	}
	private void dropPheromones(){
		getLocation().getDataHolder().dropFeasibilityAntPheromones(this.getLastRoad(), getSendingAgent().getId(), isFromPickUpPoint(), getPheromoneSmell());
		
	}
	private long getPheromoneSmell(){
		return initialPheromoneCount - getTravelledDistance();
	}
	
	/**
	 * Checks if the amount of pheromones we would drop is greater than the amount of pheromones currently present and greater than 1
	 */
	private boolean shouldDropPheromones(Road road) {
		
		double pheromonesThatWouldBeDropped = getPheromoneSmell() - road.getLength();
		boolean antHasPheromonesLeft = pheromonesThatWouldBeDropped > 1;
		boolean hasMorePheromonesThanRoad;
		Crossroad nextLocation = road.getOtherConnector(getLocation());
		if(isFromPickUpPoint()){
			hasMorePheromonesThanRoad = pheromonesThatWouldBeDropped > nextLocation.getDataHolder().getFeasibilityDataContainer().get(road).getRemainingSmellFromPackage(getSendingAgent().getId());
		}
		else{
			FeasibilityData data = nextLocation.getDataHolder().getFeasibilityDataContainer().get(road).getDropOffFeasiblityDataFromPackage(getSendingAgent().getId());
			if(data != null){
				hasMorePheromonesThanRoad = pheromonesThatWouldBeDropped > data.getRemainingSmell();
			}
			else{
				hasMorePheromonesThanRoad = true;
			}
			
			
		}
		
		return antHasPheromonesLeft && hasMorePheromonesThanRoad;
	}

	@Override
	protected void createDieEvent() {
		EventBroker.getEventBroker().notifyAll(new FeasibilityAntDiedEvent(this));
		
	}

	public long getInitialPheromoneCount() {
		return initialPheromoneCount;
	}
	
}
